package BookFiles
{
    import flash.geom.Point;

    public class MathSupport
    {
        private var A:Point;
        private var B:Point;
        private var C:Point;

        // coefficients of AB
        private var xCoeffLineAB:Number = 1;
        private var yCoeffLineAB:Number = 1;
        private var freeCoeffLineAB:Number = 1;

        //middle AB
        private var middleAB:Point;

        //coefficients of perpendicular to AB through middleAB
        private var xCoeffPerpAB:Number = 1;
        private var yCoeffPerpAB:Number = 1;
        private var freeCoeffPerpAB:Number = 1;

        //coefficients of parallel to AB through point C
        private var xCoeffParalAB:Number;
        private var yCoeffParalAB:Number;
        private var freeCoeffParalAB:Number;

        //crossPoint is intersection of  the line which is parallel AB  and goes through C Point and
        // the line which is perpendicular of AB and goes through middle AB
        private var xCrossPoint:Number;
        private var yCrossPoint:Number;
        private var crossPoint:Point;


        public function MathSupport(OnePoint:Point, OtherPoint:Point)
        {
            A = OnePoint;
            B = OtherPoint;
            calculateCoeffLineAB();
            calculateMiddleAB();
            calculateCoeffPerpAB();
            calculateFreeCoeffPerpABThroughMiddleAB();
        }



        /*
           common equation of line going through pointes A and B
           (By-Ay)x - (Bx-Ax)y - (By-Ay)Ax+(Bx-Ax)Ay=0
           Denote coefficients:
           xCoeffLineAB = By-Ay;
           yCoeffLineAB = - (Bx-Ax);
           freeCoeffLineAB = -(By-Ay)Ax+(Bx-Ax)Ay

           So: xCoeffLineAB*x + yCoeffLineAB*y + freeCoeffLineAB = 0

         */
        private function calculateCoeffLineAB():void
        {
            xCoeffLineAB = B.y - A.y;
            yCoeffLineAB = -(B.x - A.x);
            freeCoeffLineAB = -(B.y - A.y) * A.x + (B.x - A.x) * A.y;

        }

        private function calculateMiddleAB():void
        {
            middleAB = new Point((A.x + B.x) / 2, (A.y + B.y) / 2);
        }

        public function takeMiddle():Point
        {
            return middleAB;
        }

        /*
           common equation of lines which are perpendicular of AB
           -yCoeffLineAB *x + xCoeffLineAB*y + unknownFreeCoeffLineAB = 0

           Denote coefficients:
           xCoeffPerpAB = - yCoeffLineAB;
           yCoeffPerpAB = xCoeffLineAB;

           So: xCoeffPerpAB *x + yCoeffPerpAB*y + unknownFreeCoeffPerpAB = 0

         */

        private function calculateCoeffPerpAB():void
        {
            xCoeffPerpAB = -yCoeffLineAB;
            yCoeffPerpAB = xCoeffLineAB;
        }


        /*
           common equation of line which is perpendicular of AB and goes through middleAB
           xCoeffPerpAB *middleAB.x + yCoeffPerpAB*middleAb.y + unknownFreeCoeffPerpAB = 0
           unknownFreeCoeffPerpAB = - (xCoeffPerpAB *middleAB.x + yCoeffPerpAB*middleAb.y)
           Dewnote unknownFreeCoeffPerpAB through freeCoeffPerpAB
         */
        private function calculateFreeCoeffPerpABThroughMiddleAB():void
        {
            freeCoeffPerpAB = -(xCoeffPerpAB * middleAB.x + yCoeffPerpAB * middleAB.y);
        }

        public function xForFixedY(fixedY:Number):Number
        {
            if (xCoeffPerpAB)
            {
                return -(freeCoeffPerpAB + yCoeffPerpAB * fixedY) / xCoeffPerpAB;
            }
            else
                return 0;
        }

        public function yForFixedX(fixedX:Number):Number
        {
            if (yCoeffPerpAB)
            {
                return -(freeCoeffPerpAB + xCoeffPerpAB * fixedX) / yCoeffPerpAB;
            }
            else
            {
                return 0;
            }
        }

        /*
           common equation of lines which are parallel AB
           xCoeffParalAB* x + yCoeffParalAB* y + unknownFreeParalAB = 0

           xCoeffParalAB = xCoeffLineAB;
           yCoeffParalAb = yCoeffLineAB;


         */

        private function calculateCoeffPalalAB():void
        {
            xCoeffParalAB = xCoeffLineAB;
            yCoeffParalAB = yCoeffLineAB;
        }

        private function calculateFreeCoeffParalABThroughCPoint():void
        {
            freeCoeffParalAB = -(xCoeffParalAB * C.x + yCoeffParalAB * C.y);
        }

        private function calculateCrossPoint():void
        {
            xCrossPoint = (yCoeffPerpAB * freeCoeffParalAB - yCoeffParalAB * freeCoeffPerpAB) / (-yCoeffPerpAB * xCoeffParalAB + yCoeffParalAB * xCoeffPerpAB);
            yCrossPoint = (xCoeffPerpAB * freeCoeffParalAB - xCoeffParalAB * freeCoeffPerpAB) / (yCoeffPerpAB * xCoeffParalAB - yCoeffParalAB * xCoeffPerpAB);
            crossPoint = new Point(xCrossPoint, yCrossPoint);
        }

        public function reflection(point:Point):Point
        {
            C = point;
            calculateCoeffPalalAB();
            calculateFreeCoeffParalABThroughCPoint();
            calculateCrossPoint();
            var resultPoint:Point = new Point(2 * crossPoint.x - C.x, 2 * crossPoint.y - C.y);
            return resultPoint;

        }


    }
}